/*->c.vxcol */

#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <signal.h>
#include <ctype.h>
#include <time.h>

#include "h.os"
#include "h.wimp"
#include "h.flex"
#include "h.bbc"


#include "h.def"

#include "h.wos"
#include "h.main"
#include "h.ram"
#include "h.mym"


#include "h.xext"


#include "h.vxdef"


#include "h.vxcol"



/*****************************************************************************/


#define VXMAXCOLS 8

vxcolmap vxcolourmap;
vxcolmap vxoldmap;     /* normal */
                                                        /* BBGGRR00 */
int vxphysmap[VXMAXCOLS]=
                    {
                      0x00000000, /* black */
                      0x0000FF00, /* red   */
                      0x00FF0000, /* green */
                      0x00FFFF00, /* yellow r+g */
                      0xFF000000, /* blue */
                      0xFF00FF00, /* magenta r+b */
                      0xFFFF0000, /* cyan g+b */
                      0xFFFFFF00, /* white */
                    };

char vxwmap[VXMAXCOLS]=
                    {
                     0x77,       /* black  */
                     0xBB,       /* red    */
                     0xAA,       /* green  */
                     0x99,       /* yellow */
                     0x88,       /* blue   */
                     0xEE,       /* mageta */
                     0xFF,       /* cyan   */
                     0x00,       /* white  */
                    };



static int complement[8]=
{
  WHITE,
  CYAN,
  MAGENTA,
  BLUE,
  YELLOW,
  GREEN,
  RED,
  BLACK
};


int vxcolpal[VXMAXCOLS];



/* void vxcolour(int n,int wimpcol,int r,int g,int b); */


void setvxcolour(int fp)
{
 int n;
 int wcol;
 int r;
 int g;
 int b;

 n=stack[fp];
 wcol=stack[fp+2];
 r=stack[fp+3];
 g=stack[fp+4];
 b=stack[fp+5];

 if(n>=0 && n<VXMAXCOLS)
 {
  if(wcol>=0 && wcol<16)
  {
   if(r>=0 && r<256 && g>=0 && g<256 && b>=0 && b<256)
   {
    vxwmap[n]=wcol+(wcol<<4);
    vxphysmap[n]=(b<<24)+(g<<16)+(r<<8);
   }
  }
 }
}




int vxphysicalcolour(int colour)
{
 return(vxcolourmap.physc[colour]);
}


int vxlogicalcolour(int colour)
{
 int i;

 for(i=0;i<8;i++)
        if(vxcolourmap.physc[i]==colour) return(i);
 return(0);
}


int vxoldlogicalcolour(int colour)
{
 int i;

 for(i=0;i<8;i++)
  if(vxoldmap.physc[i]==colour) return(i);
 return(0);
}



int vxnewcolourmap(void)
{
 int i;

 vxoldmap=vxcolourmap;

 if(ln2bpp==4 || ln2bpp==5)
 {

  for(i=0;i<VXMAXCOLS;i++)
  {
   vxcolourmap.physc[i]=i;

   if(ln2bpp==4)
   {
    vxcolpal[i]=((vxphysmap[i] >> 11) & 0x1F)  |
                ((vxphysmap[i] >> 14) & 0x3E0) |
                ((vxphysmap[i] >> 17) & 0x7C00);
   }
   else
   {
    vxcolpal[i]=(vxphysmap[i] >> 8) & 0xFFFFFF;
   }
  }

 }
 else
 if(ln2bpp==3)
 {
  for(i=0;i<8;i++)
     vxcolourmap.physc[i]=getcolnumber(vxphysmap[i]);
 }
 else
 {
  for(i=0;i<8;i++)
     vxcolourmap.physc[i]=vxwmap[i];
 }

 for(i=0;i<8;i++)
     if(vxcolourmap.physc[i]!=vxoldmap.physc[i]) return(1);

 return(0);
}




void vxdocolourmap(vxscreen * vsc,int handle)
{
 int     y;
 int   * data;

 int     oldbits=-1;
 int     newbits=0;   /* shut up compiler */
 int     front;
 int     back;
 int     i;

 if(!vsc) return;

 for(y=0;y<(vsc->height);y++)
 {
  data=&(vsc->tvbuf[y][0]);

  for(i=0;i<40;i++)
  {
   if(oldbits==(data[i] & 0xFFFF0000)) data[i]=(data[i] & 0xFFFF) | newbits;
   else
   {
    oldbits=data[i] & 0xFFFF0000;

    back =(oldbits & 0xFF0000)>>16;
    front=(oldbits & 0xFF000000)>>24;
    front=front^back;

    front=vxoldlogicalcolour(front);
    back =vxoldlogicalcolour(back);

    front=vxphysicalcolour(front);
    back =vxphysicalcolour(back);

    front=front^back;

    newbits=(front<<24) | (back<<16);

    data[i]=(data[i] & 0xFFFF) | newbits;
   }
  }
 }

 if(handle) refreshwindow(handle);
}





/* used to set up gcol for redraws in VDATA colours */


void vxsetgcol(int colour)
{
 int wcol;
 int temp;

 wcol=vxphysicalcolour(colour);

 if(ln2bpp==4 || ln2bpp==5)
 {
  setgcol(vxphysmap[wcol]);   /* assumes physmap entries indexed in same way */
 }
 else
 if(ln2bpp==3)
 {
  temp=wcol & 0x78;
  wcol=wcol & 0x87;
  if(temp & 0x8) temp|=0x80;
  temp=temp>>1;
  temp&=0x78;
  wcol|=temp;

  bbc_gcol(0,wcol>>2);
  bbc_tint(2,wcol & 0x3);
 }
 else
 {
  wimp_setcolour(wcol & 0xF);
 }
}






void vxinvertline(int * data)
{
 int     oldbits=-1;
 int     newbits=0; /* shut up compiler */
 int     front;
 int     back;
 int     front2;
 int     back2;
 int     i;

 for(i=0;i<40;i++)
 {
  if(oldbits==(data[i] & 0xFFFF0000)) data[i]=(data[i] & 0xFFFF) | newbits;
  else
  {
   oldbits=data[i] & 0xFFFF0000;

   back =(oldbits & 0xFF0000)>>16;
   front=(oldbits & 0xFF000000)>>24;
   front=front^back;

   front2=vxlogicalcolour(front);
   back2 =vxlogicalcolour(back);

/*
   if(front2==BLACK) front=vxphysicalcolour(WHITE);
   if(front2==WHITE) front=vxphysicalcolour(BLACK);
   if(back2==BLACK)  back =vxphysicalcolour(WHITE);
   if(back2==WHITE)  back =vxphysicalcolour(BLACK);

 */

   front=vxphysicalcolour(complement[front2]);
   back= vxphysicalcolour(complement[back2]);


   front=front^back;

   newbits=(front<<24) | (back<<16);

   data[i]=(data[i] & 0xFFFF) | newbits;
  }
 }
}

